package com.fish.compiler;

import com.dny.asmtop.ASMClassLoader;
import com.dny.asmtop.CB;
import com.dny.asmtop.ClassBuilder;
import com.dny.asmtop.Command;
import com.fish.compiler.lang.CompilationUnit;
import com.fish.compiler.lang.ScopeInstruction;
import com.fish.compiler.parse.SyntaxTreeTraverser;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Queue;

/**
 * Created by jlutt on 2018-01-20.
 *
 * @author jlutt
 */
public class Compiler {

  public static void main(String[] args) throws Exception {
    new Compiler().compile("second.enk");
  }

  public void compile(String fileName) throws Exception {
    final File jFishFile = new File(fileName);
    String fileAbsolutePath = jFishFile.getAbsolutePath();
    //String className = StringUtils.remove(fileName, ".enk");
    CompilationUnit compilationUnit = new SyntaxTreeTraverser().parseTree(fileAbsolutePath);

    List<ScopeInstruction> instructionList = compilationUnit.getClassDeclaration().getCommandList();
    List<Command> commandList = new ArrayList<>();
    instructionList.forEach((x)-> {
      x.apply(commandList);
    });
    commandList.add(CB.voidReturn());

    Class<Object> testHello = ClassBuilder.create(ASMClassLoader.create(), Object.class)
        .withClassName(compilationUnit.getClassDeclaration().getClassName())
        //增加main静态方法
        .addStaticMethod("main", void.class, Collections.singletonList(String[].class),
            CB.sequence(commandList))
        .build();

    //没有对应的接口，用反射测试
    Method mainMethod = testHello.getMethod("main", String[].class);
    mainMethod.invoke(testHello, new Object[]{null});
  }
}
